<?php

/**
 * Class Lib_SMS_Main
 * 短信发送主类
 * 2022/08/01
 */
class Lib_SMS_Main
{

    private static $_mobile = null;
    /**
     * 发送短信接口
     * @param $mobile array   手机号
     * @param array code
     * @return array
     * @throws Exception
     */
    public static function sendSMS($mobile,$scene,$argv = [],$case_id=0,$extra=[],$smsSign = 0)
    {
        try {
            //手机号码校验
            if(is_array($mobile)){
                $mobile =  self::checkMobileArr($mobile);
            }else{
                $mobile = Lib_SMS_Base_Tool::checkmobile($mobile);
                $mobile = array($mobile);
            }

            if(empty($mobile)){
                return self::errorReturn(5501,'号码不能为空');
            }
            //使用的通道
            $pass = Lib_SMS_Config::$use_pass;
            $smsContent = Lib_SMS_Config::$smsContent[$scene];
            $sign = $smsSign ? $smsSign : $pass['mpass_sign'];
            $mpass_sign = Lib_SMS_Config::$sms_sign[$sign];
            if (empty($smsContent) || empty($mpass_sign)) {
                return self::errorReturn(5502,'通道配置不能为空');
            }
            $content = Lib_SMS_Base_Tool::formatText($smsContent, $argv);
            $saveData = [
                'pass' => $pass['master_pass'],
                'scene' => $scene,
                'sign' => $mpass_sign,
                'content' => $content,
                'sendStatus' => 2,
                'sendTime' => time(),
                'caseId' => $case_id,
                'mediatorId' => empty($extra['operationUid']) ? 0 : $extra['operationUid'],
                'mediator' => empty($extra['operationName']) ? '' : $extra['operationName'],
                'mediationOrganId' => empty($extra['mediationOrganId']) ? '' : $extra['mediationOrganId'],
            ];
            //除登录外，一个手机号一天只能发一条短信
            if(!in_array($scene,['logon'])){
                foreach ($mobile as $key => $val) {
                    if (Lib_Redis_String::get("SMSNUM-".$val) && $val != 17310698030) {
                        $saveData['billableNum'] = 0;
                        $saveData['uniqueCode'] = '';
                        $saveData['mobile'] = $val;
                        $saveData['sendStatus'] = 3;
                        $saveData['sendResult'] = '发送次数超限（1条/天）';
                        Module_Mediate_SmsRecord::getInstance()->singleInsert($saveData);
                        unset($mobile[$key]);
                        continue;
                    }
                    if(in_array($val,Module_Mediate_CaseLitigant::$prohibitMobile)) {
                        $saveData['billableNum'] = 0;
                        $saveData['uniqueCode'] = '';
                        $saveData['mobile'] = $val;
                        $saveData['sendStatus'] = 3;
                        $saveData['sendResult'] = '黑名单号码，禁止发送';
                        Module_Mediate_SmsRecord::getInstance()->singleInsert($saveData);
                        unset($mobile[$key]);
                        continue;
                    }
                }
                if(empty($mobile)){
                    return array('code' => 400, 'message' => '发送次数超限（1条/天）', 'data' => []);
                }
//                if($scene != 'urge-perform'){
//                    foreach ($mobile as $key => $val) {
//                        $history = Module_Mediate_SmsRecord::getInstance()->getOne(['id'],["caseId = {$case_id}","mobile = {$val}","scene = '{$scene}'",'sendStatus in (1,2,4)']);
//                        if(!empty($history)) {
//                            $saveData['billableNum'] = 0;
//                            $saveData['uniqueCode'] = '';
//                            $saveData['mobile'] = $val;
//                            $saveData['sendStatus'] = 3;
//                            $saveData['sendResult'] = '该手机号已经已发送本短信';
//                            Module_Mediate_SmsRecord::getInstance()->singleInsert($saveData);
//                            unset($mobile[$key]);
//                            continue;
//                        }
//                    }
//                    if(empty($mobile)){
//                        return array('code' => 400, 'message' => '该案件已经发送过本条短信', 'data' => []);
//                    }
//
//                }

            }
            //主通道发送短信
            $pass_obj = Lib_SMS_Adapter::getAdapter($pass['master_pass']);
            $res = $pass_obj->sendSMS($mobile, $content, $mpass_sign);
            if($res['code'] == 200){
                $zs = Lib_Function::getInstance()->utf8_strlen($mpass_sign . $content);
                $jf_count = ceil($zs / 67);
                $saveData['billableNum'] = !empty($jf_count) ? $jf_count : 1;
                $saveData['uniqueCode'] = !empty($res['data']['unique_code']) ? $res['data']['unique_code'] : '';//唯一标识
                foreach ($mobile as $k=>$v){
                    if($scene != 'logon') {
                        //记录发送
                        $str_time = strtotime(date('Y-m-d 23:59:59'));
                        Lib_Redis_String::incr("SMSNUM-".$v);
                        Lib_Redis_String::expireAt("SMSNUM-".$v,$str_time);
                    }
                    $saveData['mobile'] = $v;
                    //入库
                    Module_Mediate_SmsRecord::getInstance()->singleInsert($saveData);
                }
                return array('code' => 200, 'message' => '提交成功');
            }

            if(!empty($pass['slave_pass'])){
                //备选通道发送短信
                $spass_sign = Lib_SMS_Config::$sms_sign[$pass['spass_sign']];
                $saveData['pass'] = $pass['slave_pass'];
                $saveData['sign'] = $spass_sign;
                $pass_obj = Lib_SMS_Adapter::getAdapter($pass['slave_pass']);
                $res = $pass_obj->sendSMS($mobile, $content, $spass_sign);
                Func_Log::write('SMS', "Main_slave_pass",  $pass['slave_pass'] . ',spass_sign=' . $spass_sign);
                if($res['code'] == 200){
                    $zs = Lib_Function::getInstance()->utf8_strlen($spass_sign . $content);
                    $jf_count = ceil($zs / 67);
                    $saveData['billableNum'] = !empty($jf_count) ? $jf_count : 1;
                    $saveData['uniqueCode'] = !empty($res['data']['unique_code']) ? $res['data']['unique_code'] : '';//唯一标识
                    foreach ($mobile as $k=>$v){
                        if($scene != 'logon') {
                            //记录发送
                            $str_time = strtotime(date('Y-m-d 23:59:59'));
                            Lib_Redis_String::incr("SMSNUM-".$v);
                            Lib_Redis_String::expireAt("SMSNUM-".$v,$str_time);
                        }
                        $saveData['mobile'] = $v;
                        //入库
                        Module_Mediate_SmsRecord::getInstance()->singleInsert($saveData);
                    }
                    return array('code' => 200, 'message' => '提交成功');
                }
            }
            foreach ($mobile as $k=>$v){
                $saveData['mobile'] = $v;
                $saveData['sendStatus'] = 3;
                $saveData['sendResult'] = $res['message'];

                Module_Mediate_SmsRecord::getInstance()->singleInsert($saveData);
            }
            return array('code' => 400, 'message' => empty($res['message']) ? '' : $res['message']);
        }catch (Exception $exception) {
            Func_Log::write('SMS','Exception：'.$exception->getMessage(),'res='.json_encode([$mobile,$scene,$argv,$case_id,$extra]));
            return array('code' => 500, 'message' => $exception->getMessage());
        }

    }


    public static function sendSMS_content($mobile,$content,$scene='ajsl',$case_id=0,$extra=[],$pass='Chuanglan'){
        try {

            $mpass_sign = Lib_SMS_Config::$sms_sign[$pass];


            //主通道发送短信
            $pass_obj = Lib_SMS_Adapter::getAdapter($pass);
            $res = $pass_obj->sendSMS($mobile, $content, $mpass_sign['1']);
            if ($res['code'] ==  200) {
                $status = 2;

                //需要异步获取通知结果的 短信通过,
                $unique_code = !empty($res['data']['unique_code']) ? $res['data']['unique_code'] : '';//唯一标识

                //多个手机号分别入库,以便后期获取 准确的发送结果
                foreach ($mobile as $k=>$v){
                    $sms_id = Module_Mediate_SmsRecord::getInstance()->insert($v,$status,$pass,$scene,$mpass_sign['1'].$content,$res['message'],$case_id,$extra,$unique_code);
                }

                return array('code' => 200, 'message' => '发送成功', 'data' => ['status' => $status]);
            }



            return array('code' => 400, 'message' => isset($res['message']) ? $res['message'] : '');

        } catch (Exception $exception) {
            return array('code' => 500, 'message' => $exception->getMessage());
        }
    }

    /**
     * 效验手机数组
     * @param mobile_arr  手机号数组
     * @return mobiles 正确手机号数组
     */
    private static function checkMobileArr($mobile_arr)
    {
        $mobiles = [];
        if(!empty($mobile_arr)){
            foreach($mobile_arr as $mobile){
                $phone = Lib_SMS_Base_Tool::checkmobile($mobile);
                if(!$phone){
                    Func_Log::write('SMS', 'mobile:' . $mobile , json_encode(self::errorReturn('Spam', 5504)));
                    continue;
                }
                $mobiles[] = $mobile;

            }
        }
        return $mobiles;
    }



    public static function errorReturn($code,$message='')
    {
        return array('code' => $code, 'message' => $message);
    }

    public static function curlPost($url, $params, $header_arr=[])
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header_arr);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_NOBODY, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        $res = curl_exec($ch);

        //请求超时
        if ($res == false && curl_errno($ch) == 28) {
            curl_close($ch);
            return 28;
        }
        curl_close($ch);
        return $res;
    }
}